import Request from '@/utils/luch-request/index.js'
import { api } from '@/config/config'
import Cache,{ Keys } from '@/utils/cache.js'
import { getAccessToken } from '@/utils/getAccessToken.js'
import jwt_decode from './jwt-decode'

const http = new Request();

let expireTokenCache = [] // 储存过期的token

class Ajax {

    ajax(options = {}) {
        return http.request({
            method: options.method, // 请求方法必须大写
            url: options.url,
            data: options.data,
            // #ifdef MP-ALIPAY || MP-WEIXIN
            timeout: 30000, // 仅微信小程序（2.10.0）、支付宝小程序支持
            // #endif
            params: options.params,
            // 注：如果局部custom与全局custom有同名属性，则后面的属性会覆盖前面的属性，相当于Object.assign(全局，局部)
            custom: {
                isJson: options.isJson,
                needToken: options.needToken
            }, // 自定义参数
          })
    }
}


/** 请求之前拦截 */
http.interceptors.request.use(async (config) => {
    // 可使用async await 做异步操作

    /** 处理url */
    if (/^\/base\/.*/.test(config.url)) {
        config.url = config.url.replace('/base/','/')
        config.baseURL = api.base;
    } else if (/^\/zhibo\/.*/.test(config.url)) {
        config.url = config.url.replace('/zhibo/','/')
        config.baseURL = api.zhibo;
    } else {
        config.baseURL = api.buyer;
    }
    //设置header信息
    //uniapp统一设置头client_type=UNIAPP
    //因为目前移动端没有适合的技术支持拖拽验证
    //在服务器端判断了如果client_type=UNIAPP，则强制使用验证码验证
    config.header = {
        ...config.header,
        client:'MINI',
        clientType:'UNIAPP',
        Role: 'BUYER',
        uuid: uni.getStorageSync(Keys.uuid)
    }
    //如果需要json传递方式
    if(config.custom.isJson){
        config.header = {
            ...config.header,
            'Content-Type': 'application/json'
        }
    } else {
        config.header = {
            ...config.header,
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    }

    //如果需要Token
    if(config.custom.needToken){
        //accessToken
        const accessToken = uni.getStorageSync(Keys.accessToken);
        //refreshToken
        const refreshToken = uni.getStorageSync(Keys.refreshToken);

        //设置header信息
        config.header = {
            ...config.header,
            Authorization: accessToken,
        }
        if (refreshToken) {
            let accessExp
            if (accessToken) {
                accessExp = jwt_decode(accessToken).exp
            }
            const refreshExp = jwt_decode(refreshToken).exp
            const now = Date.now() / 1000
            if (!accessToken || (now > accessExp && now < refreshExp)) {
                try {
                    console.log('换票========>')
                    const { statusCode, data, } = await getAccessToken()
                    console.log('结果========>')
                    console.log(statusCode)
                    if (statusCode === 200) {
                        expireTokenCache = []
                        //设置header信息
                        config.header = {
                            ...config.header,
                            Authorization: data.accessToken,
                        }
                    } else {
                        // 其他情况，可能refreshToken过期了等等，请根据自身逻辑处理
                        console.log('refreshToken过期了，清空登录信息');
                        cleanAll();
                    }
                } catch (e) {
                    cleanAll();
                    console.log(e);
                    // 可能由于网络原因通过refreshToken 获取accessToken失败了;
                    //可以根据自身逻辑处理，我这里直接放弃本次请求，会进入interceptors.response的错误拦截函数
                    return Promise.reject(config)
                }
            }
        }
    }

    //设置请求参数
    if (config.params) {
        //config.data = config.params
    }
    return config
}, config => {
    // 可使用async await 做异步操作
    return Promise.reject(config)
})

// 必须使用异步函数，注意
http.interceptors.response.use(async (response) => { /* 请求之后拦截器。*/

    return response.data;
}, (response) => {
    console.log('==========返回信息=========')
    console.log(response)
    //如果是403，则清空登录信息
    if(response.statusCode == 403) {
        console.log('如果是403，则清空登录信息');
        cleanAll();
    } else if(response.statusCode == 500 || response.statusCode == 400 || response.statusCode == 401){
        uni.showToast({
            title: response.data.message,
            icon: 'none',
            duration: 2000,
        })
    }
    return Promise.reject(response)
})

//清空登录信息
function cleanAll(){
    console.log('清空登录信息')
    if (!Cache.getItem(Keys.user)) return
    uni.$emit('logout',{msg:'退出登录消息'})
    Cache.removeItem(Keys.user);
    Cache.removeItem(Keys.uid);
    Cache.removeItem(Keys.accessToken);
    Cache.removeItem(Keys.refreshToken);
    Cache.removeItem(Keys.wxauth);
    Cache.removeItem(Keys.loginResult);
    uni.navigateTo({ url: '/pages/auth/login' })
}

export default new Ajax();

export const Method = {
    GET: 'GET',
    POST: 'POST',
    PUT: 'PUT',
    DELETE: 'DELETE',
};
